package pe.integracion;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.ws.soap.SOAPFaultException;

import org.apache.log4j.Logger;
import org.w3c.dom.Node;

public class ValidarCabecera implements SOAPHandler<SOAPMessageContext> {

	final static Logger LOGGER = Logger.getLogger(ValidarCabecera.class);
	
	
	@Override
	public boolean handleMessage(SOAPMessageContext context) {
		// TODO Auto-generated method stub
		String vUsuarioWSS = "";
		String vPasswordWSS = "";
		List<Object> objListaUsuarios = null;
		List<Object> objListaPasswords = null;
		
		boolean retorno = false;
		
		try {
			Map<Object, Object> objCabeceraRequest = (Map<Object, Object>) context
					.get(MessageContext.HTTP_REQUEST_HEADERS);
			objListaUsuarios = (List<Object>) objCabeceraRequest
					.get("username");
			objListaPasswords = (List<Object>) objCabeceraRequest
					.get("password");
			
			SOAPMessage soapMsg = context.getMessage();
			SOAPEnvelope soapEnv = soapMsg.getSOAPPart().getEnvelope();
			//SOAPHeader soapHeader = soapEnv.getHeader();
			SOAPBody soapBody = soapMsg.getSOAPBody();
			
			
			
			
			
			if (objListaUsuarios != null) {
				vUsuarioWSS = objListaUsuarios.get(0).toString();
			} else {
				generateSOAPErrMessage(soapMsg,
						"Usuario no puede ser nulo.");
			}
			   
			  //Obteniendo: PASSWORD.
			if (objListaPasswords != null) {
				vPasswordWSS = objListaPasswords.get(0).toString();
			} else {
				generateSOAPErrMessage(soapMsg,
						"Clave no puede ser nula.");
			}

			LOGGER.info("- vUsuarioWSS: [" + vUsuarioWSS + "]");
			LOGGER.info("- vPasswordWSS: [" + vPasswordWSS + "]");
			
			
			
			 if( vUsuarioWSS.equals(  pe.integracion.config.Constantes.USUARIO_WSS  ) && 
		    		  vPasswordWSS.equals( pe.integracion.config.Constantes.PASSWORD_WSS ) ){	
				 retorno = Boolean.TRUE;
			 } else {
				 generateSOAPErrMessage(soapMsg,
							"Credenciales incorrectas.");
			 }
			 
			
		} catch (Exception e) {
			e.printStackTrace();
			LOGGER.error(e);
			retorno = Boolean.FALSE;
		}
		return retorno;
	}
	
	/*@Override
	public boolean handleMessage(SOAPMessageContext context) {

		System.out.println("Server : handleMessage()......");

		Boolean isRequest = (Boolean) context
				.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

		// for response message only, true for outbound messages, false for
		// inbound
		if (!isRequest) {

			try {
				SOAPMessage soapMsg = context.getMessage();
				SOAPEnvelope soapEnv = soapMsg.getSOAPPart().getEnvelope();
				SOAPHeader soapHeader = soapEnv.getHeader();
				
				// if no header, add one
				if (soapHeader == null) {
					soapHeader = soapEnv.addHeader();
					// throw exception
					generateSOAPErrMessage(soapMsg, "No SOAP header.");
				}

				// Get client mac address from SOAP header
				Iterator it = soapHeader
						.extractHeaderElements(SOAPConstants.URI_SOAP_ACTOR_NEXT);

				// if no header block for next actor found? throw exception
				if (it == null || !it.hasNext()) {
					generateSOAPErrMessage(soapMsg,
							"No header block for next actor.");
				}

				// if no mac address found? throw exception
				Node macNode = (Node) it.next();
				String macValue = (macNode == null) ? null : macNode.getValue();

				if (macValue == null) {
					generateSOAPErrMessage(soapMsg,
							"No mac address in header block.");
				}

				// if mac address is not match, throw exception
				if (!macValue.equals("90-4C-E5-44-B9-8F")) {
					generateSOAPErrMessage(soapMsg,
							"Invalid mac address, access is denied.");
				}

				// tracking
				soapMsg.writeTo(System.out);

			} catch (SOAPException e) {
				System.err.println(e);
			} catch (IOException e) {
				System.err.println(e);
			}

		}

		// continue other handler chain
		return true;
	}*/

	private void generateSOAPErrMessage(SOAPMessage msg, String reason) {
		try {
			SOAPBody soapBody = msg.getSOAPPart().getEnvelope().getBody();
			SOAPFault soapFault = soapBody.addFault();
			soapFault.setFaultString(reason);
			throw new SOAPFaultException(soapFault);
		} catch (SOAPException e) {
		}
	}

	@Override
	public boolean handleFault(SOAPMessageContext context) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void close(MessageContext context) {
		// TODO Auto-generated method stub

	}

	@Override
	public Set<QName> getHeaders() {
		final QName securityHeader = new QName(
                "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
                "Security", "wsse");
 
        final HashSet headers = new HashSet();
        headers.add(securityHeader);
 
        return headers;
	}

	

	private void cloneToNewNamespace(Node nodeToRename, SOAPElement parentElement, String prefix) throws SOAPException {
        if (nodeToRename instanceof SOAPElement) {
            SOAPElement elementToRename = (SOAPElement) nodeToRename;
            SOAPElement newElement = parentElement.addChildElement(elementToRename.getElementName().getLocalName(), prefix);
            for (int index = 0; index < elementToRename.getChildNodes().getLength(); index++) {
                Node childNode = elementToRename.getChildNodes().item(index);
                cloneToNewNamespace(childNode, newElement, prefix);
            }
        } else {
            parentElement.addTextNode(nodeToRename.getNodeValue());
        }
    }
}
